﻿using System;
using System.Collections.Generic;
using System.IO;
using NUnit.Framework;
using Controller;
namespace unittest
{
    [TestFixture]
    public class PunmpControllerTest
    {
        int remainInsulin = 100;
        int cumulativeDose = 0;
        int safeMin = 3;
        int safeMax = 15;
        int maxDailyDose = 35;
        int maxDose = 10;
        int minDose = 1;
        bool isNeedle = true;
        bool availableInsulinResorvoir = true;
        List<Log> listOfLogRecords = new List<Log>();

        private bool DeliveryInsulin(int insulinDose)
        {

            //Delivery Pump Fail Tester
            //
            if (!CheckNeedle() || !CheckInsulinReservoir())
            {
                return false;
            }

            //Delivery Pump Fail Tester
            //
         
            if (remainInsulin >= insulinDose)
            {
                remainInsulin -= insulinDose;
                cumulativeDose += insulinDose;
            }
            else
            {
               
                return false;
            }
            return true;
        }
        
        [TestCase(14, true)]
        [TestCase(110, false)]
        public void DeliveryInsulinTest(int insulinDose, bool result)
        {
            remainInsulin = 100;
            isNeedle = availableInsulinResorvoir = true;
            Assert.AreEqual(result,DeliveryInsulin(insulinDose));
        }

        [TestCase(45, false)]
        public void DeliveryInsulinTest_2(int insulinDose, bool result)
        {
            isNeedle = false;
            remainInsulin = 100;
            Assert.AreEqual(result, DeliveryInsulin(insulinDose));
        }

         [TestCase(56, false)]
        public void DeliveryInsulinTest_3(int insulinDose, bool result)
        {
            availableInsulinResorvoir = false;
            remainInsulin = 100;
            Assert.AreEqual(result, DeliveryInsulin(insulinDose));
        }

        private bool SetDose(int insulinDose)
        {
            return DeliveryInsulin(insulinDose);
        }


        [TestCase(99, true)]
        [TestCase(150, false)]
        public void SetDoseTest(int insulinDose, bool result)
        {
            remainInsulin = 100;
            availableInsulinResorvoir = isNeedle = true;
            Assert.AreEqual(result, DeliveryInsulin(insulinDose));
        }

        private int ComputeInsulinDose(float bloodLevel)
        {
            float insulinDose = 0;
            if (bloodLevel < safeMin)
            {
                return 0;
            }
            else if (bloodLevel >= safeMin && bloodLevel <= safeMax)
            {
                int noOfRecored = listOfLogRecords.Count;
                if (noOfRecored >= 2)
                {
                    if (((bloodLevel - listOfLogRecords[noOfRecored - 1].BloodLevel) > 0) && ((listOfLogRecords[noOfRecored - 1].BloodLevel - listOfLogRecords[noOfRecored - 2].BloodLevel) > 0))
                    {
                        insulinDose = (bloodLevel - listOfLogRecords[noOfRecored - 1].BloodLevel) / 4;
                    }
                    else
                        return 0;
                }
                else
                    insulinDose = (bloodLevel / 4);
            }
            else
            {
                int noOfRecored = listOfLogRecords.Count;
                if (noOfRecored >= 2)
                {
                    if (!(((bloodLevel - listOfLogRecords[noOfRecored - 1].BloodLevel) < 0) && ((listOfLogRecords[noOfRecored - 1].BloodLevel - listOfLogRecords[noOfRecored - 2].BloodLevel) < 0)))
                    {
                        insulinDose = (bloodLevel - listOfLogRecords[noOfRecored - 1].BloodLevel) / 4;
                    }
                    else
                        return 0;
                }
                else
                    insulinDose = (bloodLevel / 4);
            }

            if ((cumulativeDose + insulinDose) > maxDailyDose)
            {
                insulinDose = (cumulativeDose + insulinDose) - maxDailyDose;
            }
            else if (insulinDose > maxDose)
            {
                insulinDose = maxDose;
            }
            else if (insulinDose < minDose)
            {
                insulinDose = minDose;
            }
            return (int)insulinDose;
        }

        [TestCase(2,0)]
        [TestCase(10, 1)]
        [TestCase(23, 2)]
        [TestCase(20, 5)]
        [TestCase(15, 1)]
        [TestCase(6, 1)]
        [TestCase(11, 3)]
        [TestCase((float)0.5, 0)]
        public void ComputeInsulinDoseTest(float bloodLevel, int result)
        {
            listOfLogRecords.Clear();
            cumulativeDose = 0;
            if (bloodLevel == 10)
            {
                Log log1 = new Log(DateTime.Now, 0, 9);
                Log log2 = new Log(DateTime.Now, 0, 8);
                listOfLogRecords.Add(log2);
                listOfLogRecords.Add(log1);
            }
            else if (bloodLevel == 23)
            {
                Log log1 = new Log(DateTime.Now, 0, 15);
                Log log2 = new Log(DateTime.Now, 0, 14);
                listOfLogRecords.Add(log2);
                listOfLogRecords.Add(log1);
            }
            else if (bloodLevel == 20)
            {
                Log log1 = new Log(DateTime.Now, 0, 15);
                listOfLogRecords.Add(log1);
            }
            else if (bloodLevel == 15)
            {
                Log log1 = new Log(DateTime.Now, 0, 9);
                Log log2 = new Log(DateTime.Now, 0, 8);
                listOfLogRecords.Add(log2);
                listOfLogRecords.Add(log1);
            }
            else if (bloodLevel == 6)
                cumulativeDose = 5;
            else if(bloodLevel ==  11 || bloodLevel == 0.5f)
                cumulativeDose = 36;
            Assert.AreEqual(result, ComputeInsulinDose(bloodLevel));
        }

        private float MeasureBlood()
        {
            float resultMeasure = 0;
            if (!File.Exists("bloodLevel.param"))
            {
                Random rdBloodLevel = new Random();
                resultMeasure = (float)((rdBloodLevel.Next(1, 34)) + Math.Round(rdBloodLevel.NextDouble(), 1));
            }
            else
            {
                String txtContent = File.ReadAllText("bloodLevel.param");
                resultMeasure = (float)Convert.ToDouble(txtContent);
                File.Delete("bloodLevel.param");
                if (resultMeasure < 1 || resultMeasure > 35)
                    return 0;
            }
            return resultMeasure;
        }

        [TestCase(-1,0)]
        [TestCase(15, 15)]
        [TestCase(100, 0)]
        [TestCase((float)34.9, (float)34.9)]
        public void MeasureBloodTest(float value, float result)
        {
            File.WriteAllText("bloodLevel.param", Convert.ToString(value));
            Assert.AreEqual(result, MeasureBlood());
        }

        private bool CheckNeedle()
        {
            // Needle Remove Tester
            //
            if (File.Exists("needle.param"))
            {
                isNeedle = Convert.ToBoolean(File.ReadAllText("needle.param"));
                File.Delete("needle.param");
            }
            return isNeedle;
        }

        [TestCase(true, true)]
        [TestCase(false, false)]
        public void checkNeedleTest(bool value , bool result)
        {
            File.WriteAllText("needle.param", value.ToString());
            Assert.AreEqual(result, CheckNeedle());
        }

        private bool CheckInsulinReservoir()
        {
            // Insulin Reservoir Removed Tester
            //
            if (File.Exists("insulinResevoir.param"))
            {
                availableInsulinResorvoir = Convert.ToBoolean(File.ReadAllText("insulinResevoir.param"));
                File.Delete("insulinResevoir.param");
            }
            return availableInsulinResorvoir;
        }

        [TestCase(true, true)]
        [TestCase(false, false)]
        public void CheckInsulinReservoirTest(bool value, bool result)
        {
            File.WriteAllText("insulinResevoir.param", value.ToString());
            Assert.AreEqual(result, CheckInsulinReservoir());
        }
    }

    public class TesterTest
    {
        
        private int CheckPin()
        {
            int remainPIN = 100;
            // Pin Tester
            //
            if (File.Exists("PIN.param"))
            {
                String txtContent = File.ReadAllText("PIN.param");
                remainPIN = Convert.ToInt16(txtContent);
                File.Delete("PIN.param");
            }
            if (remainPIN < 0 || remainPIN > 100)
                return 0;
            return remainPIN;
        }

        [TestCase(50,50)]
        [TestCase(100, 100)]
        [TestCase(-1, 0)]
        [TestCase(101, 0)]
        public void CheckPinTest(int value, int result)
        {
            File.WriteAllText("PIN.param", value.ToString());
            Assert.AreEqual(result, CheckPin());
        }
    }
}
